package com.yc.txx.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yc.txx.entity.User;
import com.yc.txx.mapper.UserMapper;
import com.yc.txx.service.BizException;
import com.yc.txx.service.IUserService;
import com.yc.txx.util.QRCodeUtils;
import com.yc.txx.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;
import redis.clients.jedis.Jedis;

import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.Map;
import java.util.UUID;

/**
 * <p>
 * 天下行租车-用户表-4 前端控制器
 * </p>
 *
 * @author baomidou
 * @since 2024-05-07
 */
@RestController
@RequestMapping("/txx/user")
public class UserController {

    @Autowired
    IUserService userService;

    @Autowired
    UserMapper userMapper;

    @RequestMapping("login")
    public Result login(User user, HttpSession session) throws BizException {
        user = userService.login(user);
        session.setAttribute("loginedUser", user);
        return Result.ok("登录成功!", user);
    }

    @RequestMapping("myinfo")
    public Result myinfo(@SessionAttribute(required = false) User loginedUser){
        if(loginedUser == null){
            return Result.fail("请登录系统");
        } else {
            return Result.ok("已登录", loginedUser);
        }
    }

    @RequestMapping("findById")
    public Result findById(String id){
        return Result.ok("找到用户信息",userMapper.selectById(id));
    }

    @RequestMapping("update")
    public Result update(User user,@SessionAttribute User loginedUser) throws BizException {
        userService.updateUserInfo(user);
        //更新用户基本信息
        loginedUser.setCname(user.getCname());
        loginedUser.setEamil(user.getEamil());
        loginedUser.setHeadimg(user.getHeadimg());
        return Result.ok("信息更新成功");
    }

    @RequestMapping("upPwd")
    public Result upPwd(User user,String oldPwd,String newPwd,HttpSession session) throws BizException {

        user.setPassword(oldPwd);
        userService.upPwd(user,newPwd);//修改密码
        // 修改密码了，直接销毁。让用户重新登录
        session.invalidate();
        return Result.ok("密码修改成功");
    }


    @RequestMapping("logout")
    public ModelAndView logout(ModelAndView mav, HttpSession session){
        session.invalidate();
        // 这里不需要加 上下文路径,
        String path = "redirect:/index.html";
        System.out.println("path = " + path);
        mav.setViewName(path);
        return mav;
    }

    @RequestMapping("reg")
    public Result register(@RequestBody @Valid User user, Errors errors) throws BizException {
        if(errors.hasErrors()){
            return Result.fail("字段验证失败", errors.getAllErrors());
        }
        try {
            userService.register(user);
            return Result.ok("注册成功");
        } catch (BizException e) {
            String fieldName = e.getData().toString();
            errors.rejectValue(fieldName, fieldName + ".exists", e.getMessage());
            throw new BizException("字段验证失败", errors.getAllErrors());
        }
    }

    @PostMapping("upload")
    public Result upload(@RequestParam("file") MultipartFile file) throws IOException {
        System.out.println("上传文件的字段名(请求参数名) file.getName() = " + file.getName());
        System.out.println("上传文件名 file.getOriginalFilename() = " + file.getOriginalFilename());

        String newName = UUID.randomUUID().toString();
        String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        File fileObj = new File("E:\\上课视频\\136\\0514\\upload\\" + newName + suffix);
        //File fileObj = new File("D:\\浏览器下载\\测试图片\\upload\\" + newName + suffix);
        file.transferTo(fileObj);
        // 单文件上传
        return Result.ok("文件上传成功!", newName+suffix);
    }

    @PostMapping("upload1")
    public Result upload1(@RequestParam("file") MultipartFile[] file){
        // 多文件上传
        return null;
    }

    @PostMapping("upload2")
    public Result upload1(@RequestParam("imageFile") MultipartFile imageFile,
                          @RequestParam("docFile") MultipartFile[] docFile){
        // 多文件上传
        return null;
    }

    /*
    扫码登录:
    1. 长期在线的手机端( 安卓 + HTML )
    2. PC要求登录, 获取一个二维码的登录码
            二维码是字符串生成的图片
            字符串 => URL 地址
    3. 手机扫码访问二维码对应的地址(控制器)	, 服务器记录手机的用户信息
    4.	PC会不断轮询该二维码的对应用户信息, 只要查询到用户信息
    5. PC用获取到的用户信息完成登录`
     */


//    Map<String,Object> qrMap = new Hashtable<>();

    @RequestMapping(path="createQr", produces = MediaType.IMAGE_PNG_VALUE)
    public void createQrcode(OutputStream out, HttpSession session) throws Exception {
        String qrcode = UUID.randomUUID().toString();
        // 存入扫描状态
        putToRedis(qrcode,"0");
        session.setAttribute("qrcode", qrcode);
        String url = "http://192.168.1.12:8080/demo_txx_war_exploded/txx/user/scanQrcode?qrcode=" + qrcode;
        QRCodeUtils.encode(url,null,out,false);
    }

    // 扫码方法
    @RequestMapping("scanQrcode")
    public Object scanQrcode(String qrcode,
                             @SessionAttribute(required = false) User loginedUser,
                             ModelAndView mav){
        if(loginedUser == null){
            mav.setViewName("redirect:/login.html");
            return mav;
        }
        // 扫码成功, 保存用户信息
        // json
        ObjectMapper mapper = new ObjectMapper();
        String json = null;
        try {
            json = mapper.writeValueAsString(loginedUser);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        putToRedis(qrcode, json);
//        System.out.println("--------------------qrMap = " + qrMap);
        return Result.ok("扫码成功!");
    }

    @RequestMapping("refreshQr")
    public Result refreshQr(@SessionAttribute(required = false) String qrcode,
                            HttpSession session){
        if(qrcode==null){
            return Result.fail("二维码还未生成");
        }
//        System.out.println("*******************qrMap = " + qrMap);
//        Object object = qrMap.get(qrcode);
        String json = getFromRedis(qrcode);
//        if(object instanceof User){
        if("0".equals(json) ==  false){
            ObjectMapper mapper = new ObjectMapper();
            User user;
            try {
                user = mapper.readValue(json, User.class);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            // 扫码登录成功!
            session.setAttribute("loginedUser", user);
            session.removeAttribute("qrcode");
//            qrMap.remove(qrcode);
            delFromRedis(qrcode);
            return Result.ok("登录成功", user);
        } else {
            return Result.fail("还未扫码", null);
        }
    }

    public void putToRedis(String qrcode, String value){
        try(Jedis jedis = new Jedis("127.0.0.1",6379);){
            jedis.set(qrcode, value);
        }
    }

    public String getFromRedis(String qrcode){
        try(Jedis jedis = new Jedis("127.0.0.1",6379);){
            return jedis.get(qrcode);
        }
    }

    public void delFromRedis(String qrcode){
        try(Jedis jedis = new Jedis("127.0.0.1",6379);){
            jedis.del(qrcode);
        }
    }
}
